package com.ruoyi.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.Utils;
import com.ruoyi.core.domain.ClientProductUser;
import com.ruoyi.core.lock.ULock;
import com.ruoyi.core.mapper.ClientProductUserMapper;
import com.ruoyi.core.service.MSearchService;
import com.ruoyi.core.vo.SearchResultVo;
import com.ruoyi.core.vo.SearchVo;
import com.ruoyi.system.domain.ClientProductSys;
import com.ruoyi.system.mapper.ClientUserMapper;
import com.ruoyi.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @Author xiaom
 * @Date 2021/1/26 19:05
 * @Version 1.0.0
 * @Description <>
 **/
@Service
@Slf4j
public class MSearchServiceImpl implements MSearchService {

    private final static String crawlerUrl = "http://127.0.0.1:3025/do";

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ClientProductUserMapper clientProductUserMapper;

    @Autowired
    private ClientUserMapper clientUserMapper;

    @Autowired
    private ISysConfigService sysConfigService;

    @Override
    @Cacheable(cacheNames = "merchant_result#1814400",key = "#searchVo.type + ':' + #searchVo.path")
    @ULock(lockKey = "#{searchVo.type}",interval = 3)
    public Object request(SearchVo searchVo) {
        //Inject Cookies
        injectCookie(searchVo);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(getCrawlerUrl());
        searchVo.toMap().forEach(builder::queryParam);
        log.info("Send Request Address:{} params:{}",getCrawlerUrl(),JSON.toJSONString(searchVo));
        ResponseEntity<SearchResultVo> responseEntity = restTemplate.getForEntity(builder.build().encode().toString(), SearchResultVo.class);
        SearchResultVo result = responseEntity.getBody();
        log.info("Result:{}", JSON.toJSONString(result));
        if(result != null && result.getData().getCode().equals(HttpStatus.SUCCESS)){
            return result;
        }
        throw new CustomException("查询失败");
    }

    private String getCrawlerUrl(){
        Object url = sysConfigService.selectConfigByKey("merchant_words_crawler_url");
        if(url == null){
            log.error("魔词爬虫服务器未配置");
            throw new CustomException("服务器系统错误");
        }
        return url.toString();
    }

    private void injectCookie(SearchVo searchVo) {

        ClientProductSys clientProductSys = clientUserMapper.findClientProductByName("merchantwords_web");

        //获取魔词cookie集合
        List<ClientProductUser> list = clientProductUserMapper.findByProductId(clientProductSys.getId());
        if(list == null || list.isEmpty()){
            log.error("未设置魔词web版cookie");
            throw new CustomException("系统配置异常");
        }
        //随机获取一个cookie
        searchVo.setCookie(list.get(Utils.getRandomNumberInRange(0,list.size() - 1)).getCookie());
    }

    @Override
    public Boolean clearCache() {
        String cacheKeyPrefix = "merchant_result**";
        Collection<String> list = redisCache.keys(cacheKeyPrefix);
        if(list.size() <= 0){
            return true;
        }
        redisCache.deleteObject(list);
        return true;
    }
}
